<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * 记录当前生成的扫码页信息
 * swoole_tabel 实例
 */

// ------------------------------------------------------------------------

class Client_swoole extends Threads
{

    private static $table;

    /**
     * 初始化
     * 需要在 $server->start() 之前执行
     *
     * @return void
     */
    public function init()
    {
        if (empty(self::$table)) {
            // 仅允许拥有一个实例
            $table = new swoole_table(1024);
            $table->column('fd', swoole_table::TYPE_INT); // 系统给客户端标记的自增 ID
            $table->column('client_id', swoole_table::TYPE_STRING, 20); // 对应的客户端 ID
            $table->column('time', swoole_table::TYPE_INT, 10); // 创建的时间，用来验证二维码是否超时
            $table->column('scanned', swoole_table::TYPE_STRING, 20); // 用来标记该二维码是否被成功扫描过（如果扫过的话会记录扫描者的 fd）
            $table->create();
            self::$table = $table;
        }
    }

    public function client_validation($client_id){
        if($client_id = decrypt($client_id)){
            return $client_id;
        }else{
            return FALSE;
        }
    }

    /**
     * 新增扫码客户端数据
     * 如果存在的话则会重置
     *
     * @param int $fd 该客户端在服务器中的标记 ID
     * @param string $client_id 扫码客户端的唯一 ID，通过 websocket 传递
     * @return void
     */
    public function create($fd, $client_id)
    {
        $client_id = $this->client_validation($client_id);
        self::$table->set($client_id, array('fd' => $fd, 'client_id' => $client_id, 'time' => time(), 'scanned' => ''));
    }

    /**
     * 获取指定扫码客户端的信息
     * 如果信息不存在将会返回 FALSE
     *
     * @param string $client_id 扫码客户端的唯一 ID，通过 websocket 传递
     * @return array
     */
    public function get($client_id)
    {
        $client_id = $this->client_validation($client_id);
        return self::$table->get($client_id);
    }

    /**
     * 判断客户端中的二维码是否已经被其他设备扫描
     *
     * @param string $client_id 扫码客户端的唯一 ID，通过 websocket 传递
     * @param int $scanner_fd 当前扫描设备客户端的 fd
     * @return bool
     */
    public function is_scanned($client_id, $scanner_fd)
    {
        $info = $this->get($client_id);
        if (!empty($info['scanned']) && $info['scanned'] != $scanner_fd) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * 判断客户端中二维码是否已经过期
     *
     * @param string $client_id 扫码客户端的唯一 ID，通过 websocket 传递
     * @return bool
     */
    public function is_expired($client_id)
    {
        $info = $this->get($client_id);
        if ($info['time'] < time() - $this->config->item('qrcode_valid_time') * 60) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * 将客户端标记为已扫码状态
     *
     * @param string $client_id 扫码客户端的唯一 ID，通过 websocket 传递
     * @param int $scanner_fd 当前扫描设备客户端的 fd
     * @return void
     */
    public function scan($client_id, $scanner_fd)
    {
        $client_id = $this->client_validation($client_id);
        self::$table->set($client_id, array('scanned' => $scanner_fd));
    }

    /**
     * 清除扫码客户端的信息
     * 一般在客户端断开连接后使用
     *
     * @param int $fd 客户端的 fd
     * @return bool
     */
    public function close($fd)
    {
        foreach (self::$table as $table) {
            if ($table['fd'] == $fd) {
                // 该客户端是扫码客户端，清除
                self::$table->del($table['client_id']);
                break;
            }elseif($table['scanned'] == $fd){
                // 该客户端是扫描设备客户端，重置扫码状态
                self::$table->set($table['client_id'], array('scanned' => ''));
            }
        }
    }

}